﻿using Magicodes.ExporterAndImporter.Excel;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business.CXYXTHNR;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Reports.CBBYS.Dtos;
using NP.BPMReportPlatform.Reports.CXYXTHNRA.Dtos;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Utils;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Reports.DailyCloseBook.Dtos;

namespace NP.BPMReportPlatform.Reports.CBBYS
{
    public class CBBYSService : BPMReportPlatformAppService, ICBBYSService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly SqlSugarClient _dbEngine;
        private readonly ILogger _logger;
        private readonly IExcelImporter _importer;

        public CBBYSService(
            ISqlSugarAppService sqlSugarAppService
            , IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp
            , ILogger logger, IExcelImporter importer)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _logger = logger;
            _importer = importer;
        }

        public async Task<PagedResultDto<GetCBBYSOutput>> GetAllAsync(GetCBBYSInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId));

            //返回结果
            return new PagedResultDto<GetCBBYSOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        private ISugarQueryable<GetCBBYSOutput> GetQueryable(GetCBBYSInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }

            var notViewStarter = _db.Queryable<KeyValues>().Where(x => x.CatalogCode == "CBBYSNotViewStarter").Select(x => x.Code).ToList();
            var startUsers = _dbPlatform.Queryable<Users>().Where(x => SqlFunc.ContainsArray(notViewStarter, x.WorkNumber)).Select(x => x.UserId).ToList();
            var listQueryable = _db.Queryable<StandardApproval, BusinessProcessesNew>(
                    (x, b) => new JoinQueryInfos(JoinType.Left, x.InstanceId == b.InstanceId && b.BTID == "CBBYS"))
                .Where((x, b) => x.FlowType == "CBBYS" && !SqlFunc.ContainsArray(startUsers, x.AddUserId))
                .WhereIF(!input.IsQueryAll, x => x.AddUserId.Equals(currentUserId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), x => x.InstanceId == input.InstanceNumber)
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, b) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), b.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), x => x.AddUserName.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                    x => x.AddTime >= input.StartCreationTime && x.AddTime <= input.EndCreationTime)
                .WhereIF(!string.IsNullOrWhiteSpace(input.Title), x => x.Title.Contains(input.Title))
                .Select((x, b) => new GetCBBYSOutput()
                {
                    InstanceNumber = x.InstanceId,
                    ProcessStartTime = x.AddTime,
                    ProcessStartTimeStr = x.AddTime.ToString(DateFormatHelper.DateTimeFormat),
                    ProcessStartUserName = x.AddUserName,
                    OrderStatus = b.ProcessStatusName,
                    FinishTime = b.FinishTime,
                    FinishTimeStr = b.FinishTime != null && b.FinishTime != DateTime.MinValue ? b.FinishTime.Value.ToString(DateFormatHelper.DateTimeFormat) : "",
                    Title = x.Title,
                    Content = x.Content,
                }).MergeTable().Distinct().OrderBy(ins => ins.ProcessStartTime, OrderByType.Desc);
            return listQueryable;
        }

        public async Task<List<GetCBBYSOutput>> ExportAsync(GetCBBYSInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();

            return listViewDto;
        }
    }
}
